package cc.rengu.redp.bizimpl.upmp.controller;


import cc.rengu.redp.bizimpl.bean.LabelValueBean;
import cc.rengu.redp.bizimpl.constant.UpmpConstant;
import cc.rengu.redp.bizimpl.enums.IgasYesOrNoEnum;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpRole;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpRoleMenu;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpSysParam;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpRoleMenuService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpRoleService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpSysParamService;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpRoleVO;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.bizimpl.utils.CommonUtils;
import cc.rengu.redp.bizimpl.utils.RedpUpmpUtil;
import cc.rengu.redp.common.annotation.Log;
import cc.rengu.redp.common.controller.BaseController;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.domain.RedpResponse;
import cc.rengu.redp.common.exception.RedpException;
import cc.rengu.redp.common.utils.RedpUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.wuwenze.poi.ExcelKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author System
 */
@RestController
@RequestMapping("/admin/upmprole")
@Slf4j
public class UpmpRoleController extends BaseController {

    @Autowired
    private IUpmpRoleService upmpRoleService;
    @Autowired
    private IUpmpRoleMenuService upmpRoleMenuService;
    @Autowired
    private IUpmpSysParamService upmpSysParamService;

    @Autowired
    private ObjectMapper mapper;

    @GetMapping
//    @RequiresPermissions("role:view")
    public Map<String, Object> roleList(QueryRequest queryRequest, UpmpRoleVO role) {
        return getDataTable(upmpRoleService.findRoles(role, queryRequest));
    }

    @GetMapping("getAll")
    public List<UpmpRole> getAll(UpmpRoleVO role) {
        return upmpRoleService.getAllRoles(role);
    }

    @GetMapping("check")
    public RedpResponse checkRoleName(@NotBlank(message = "{required}")  String instId, @NotBlank(message = "{required}") String roleName) {
        List<UpmpRole> result = this.upmpRoleService.findByName(instId,roleName);
        if(ObjectUtils.isEmpty(result)){
            return RedpResponse.getInstance().success();
        }else{
            return RedpResponse.getInstance().failure();
        }
    }

    @GetMapping("menu/{roleId}")
    public List<String> getRoleMenus(@NotBlank(message = "{required}") @PathVariable String roleId) {
        List<UpmpRoleMenu> list = this.upmpRoleMenuService.getRoleMenusByRoleId(roleId);
        return list.stream().map(roleMenu -> String.valueOf(roleMenu.getMenuId())).collect(Collectors.toList());
    }

    @Log("新增角色")
    @PostMapping
    @RequiresPermissions("role:add")
    public void addRole(@Valid UpmpRoleVO role) throws RedpException {
        try {
            this.upmpRoleService.createRole(role);
        } catch (Exception e) {
            String message = "新增角色失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @Log("删除角色")
    @DeleteMapping("/{roleIds}")
    @RequiresPermissions("role:delete")
    public void deleteRoles(@NotBlank(message = "{required}") @PathVariable String roleIds) throws RedpException {
        try {
            String[] ids = roleIds.split(StringPool.COMMA);
            this.upmpRoleService.deleteRoles(ids);
        } catch (Exception e) {
            String message = "删除角色失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @Log("修改角色")
    @PutMapping
    @RequiresPermissions("role:update")
    public void updateRole(UpmpRoleVO role) throws RedpException {
        try {
            this.upmpRoleService.updateRole(role);
        } catch (Exception e) {
            String message = "修改角色失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("excel")
    @RequiresPermissions("role:export")
    public void export(QueryRequest queryRequest, UpmpRoleVO role, HttpServletResponse response) throws RedpException {
        try {
            List<UpmpRole> roles = this.upmpRoleService.findRoles(role, queryRequest).getRecords();
            ExcelKit.$Export(UpmpRole.class, response).downXlsx(roles, false);
        } catch (Exception e) {
            String message = "导出Excel失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    /**
     * 获取法人行进行新增、修改、删除等操作时支持操作的角色级别
     * @param instId
     * @return
     * @throws RedpException
     */
    @GetMapping("getRoleCode/{instId}/{pageOptFlag}")
//    @RequiresAuthentication
    public List<LabelValueBean> getRoleLevelList(@NotBlank(message = "{required}") @PathVariable String instId,@NotBlank(message = "{required}") @PathVariable String pageOptFlag) throws RedpException {
        UpmpSysParam defaultInst = upmpSysParamService.getById(UpmpConstant.DEAFULT_INST_PARAM_ID);
        //此处先手动初始化，后续改成通过RedpUpmpUtil获取
        UpmpUserInfoVO currentUser = CommonUtils.getCurrentUser(upmpSysParamService);
        List<LabelValueBean> result = Lists.newArrayList();
        LabelValueBean firt = new LabelValueBean("","请选择");
        result.add(firt);
        List<UpmpSysParam> instList = Lists.newArrayList();
        if(currentUser.isAdmin()){//系统超级管理员加载的角色
            if(defaultInst.getPrimaryValue().equals(instId)){
                instList =  upmpSysParamService.findChildrenByPrimaryKey(UpmpConstant.SYS_DEFAULT_INST_SURPORT_ROLES_PARAM,defaultInst.getInstId(),null);
            }else{
                instList =  upmpSysParamService.findChildrenByPrimaryKey(UpmpConstant.SYS_INST_SURPORT_ROLES_PARAM,defaultInst.getInstId(),null);
            }

        }else{
            if(defaultInst.getPrimaryValue().equals(currentUser.getInstId())){
                instList =  upmpSysParamService.findChildrenByPrimaryKey(UpmpConstant.SYS_DEFAULT_INST_SURPORT_ROLES_PARAM,defaultInst.getInstId(),null);
            }else if(instId.equals(currentUser.getInstId())&&!defaultInst.equals(currentUser.getInstId())){
                instList =  upmpSysParamService.findChildrenByPrimaryKey(UpmpConstant.SYS_INST_SURPORT_ROLES_PARAM,defaultInst.getInstId(),null);
            }else{//不是默认法人行的管理员不能设置其他行的法人的角色
                log.error("非法操作：不是默认法人行的管理员获取非本人所在法人行的角色信息");
                throw new RedpException("非法操作");
            }
        }
        instList.forEach(inst->{
            if(UpmpConstant.SYS_INST_SURPORT_ROLES_OPR_SURPORT_FLAG_PARAM.equals(inst.getSecondaryKey())
                && !StringUtils.isEmpty(inst.getSecondaryValue())){//如果设置了操作类型是否支持的参数则进行判断,此时SecondaryValue用来保存角色的 新增、修改、删除等操作是否支持
                boolean surport = false;
                try {
                    List<LabelValueBean> oprSurportFlags= this.mapper.readValue(inst.getSecondaryValue(), new TypeReference<List<LabelValueBean>>() {});
                    if(!ObjectUtils.isEmpty(oprSurportFlags)){
                        for(LabelValueBean oprSurportFlag:oprSurportFlags ){
                            if(pageOptFlag.equals(oprSurportFlag.getLabel())
                                && IgasYesOrNoEnum.Yes.getType().equals(oprSurportFlag.getValue())){
                                surport = true;
                                break;
                            }
                        }
                    }
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                if(surport){
                    LabelValueBean labelValueBean = new LabelValueBean(inst.getPrimaryKey(), inst.getPrimaryValue());
                    result.add(labelValueBean);
                }
            }else {
                LabelValueBean labelValueBean = new LabelValueBean(inst.getPrimaryKey(), inst.getPrimaryValue());
                result.add(labelValueBean);
            }
        });
        return result;
    }
}
